home *** CD-ROM | disk | FTP | other *** search
- /* TOILET.KB */
- /* Flush toilet simulation */
- /* Load this knowledge base from MIKE as follows:
- ?- kb 'toilet.kb'.
-
- Run the simulation by invoking the forward chainer as follows:
- ?- fc.
- */
- /* There are only 3 elements:
- float1, tank1, and pipe1. pipe1 starts off with a flow rate of 5,
- and tank1 starts off at level 0. We only do integer
- arithmetic: as the float rises, the flow rate decreases
- from 5 to 3 to 1 to 1 (again, due to integer division), then to 0.
- At the same time,
- the float1 height goes from 0 to 5 to 8 to 9 to 10.
- Flow rate is simply (hard wired) to be 5 - (FloatHeight//2)
- so at the end of each respective cycle of the rule interpreter
- this is (5 - (0//2)) and then (5 - (5//2) and then (5 - (8//2)) and then
- (5 - (9//2)) and then finally (5 - (10//2)) when it stops.
- */
-
- /* first rule clears 'start' symbol from working memory, then
- dynamically alters the conflict resolution strategy so that
- only refractoriness is used (and not specificity or recency).
- */
-
- rule init forward
- if
- start /* special symbol which is always in WM at start */
- then
- remove start &
- strategy [refractoriness] & /* SPECIFITY IS TABOO HERE */
- /* so is recency in this context (this differs slightly from text) */
- /* the following is a good example of the difference between note and
- add. note acts on frame memory and its effects are both permanent
- and it will overwrite the preceding contents. Its effects are therefore
- destructive. add on the otherhand adds the new term to working memory.
- Any previous terms are not removed, and the effects of working memory
- are cleaned up on every run of the rule interpreter */
- note the level of tank1 is 0 &
- add tank_filling. /* begin with empty tank, but fill it up first */
-
-
- rule stop_it forward
- if
- tank_filling &
- the level of tank1 > 9 /* will eventually reach this */
- then
- strategy [refractoriness, recency, specificity] & /* restore defaults */
- halt .
-
- rule filling forward
- if
- tank_filling &
- the level of tank1 is L &
- the flow_rate of pipe1 is R
- then
- prolog(NewLevel is L + R) & /* must call prolog to do sums */
- note the level of tank1 is NewLevel. /* this triggers change_rule */
- /* this OVERWRITES former level of tank1 !!!!! */
-
-
- tank1 instance_of tank with
- height: 5,
- width: 4,
- depth: 3,
- regulator: float1.
-
- float1 instance_of float with
- arm_length: 4,
- regulated_inlet: pipe1.
-
- pipe1 instance_of pipe with
- thickness: 5,
- comes_from: mains_supply,
- goes_to: tank1,
- flow_rate: 5. /* starting flow_rate is 5, gets changed later */
-
-
- pipe subclass_of flow_through_device with
- material: copper.
-
- tank subclass_of vessel with
- /* next slot not used at moment, but illustrates the syntax */
- volume:
- [value: V,
- access_rule: (if the height of ?self is H &
- the width of ?self is W &
- the depth of ?self is D &
- prolog(V is H*W*D)
- then
- make_value V)],
- level :
- [value: L,
- change_rule : (if the regulator of ?self is Reg
- then
- prolog(draw_image('level of tank 1',L)) &
- note the height of Reg is L)].
-
- float subclass_of regulating_feedback_valves with
- arm_length: AL,
- regulated_inlet: P,
- height :
- [value: H,
- change_rule: (if the regulated_inlet of ?self is Inlet /* e.g. pipe1 */
- then
- prolog(NewFlowRate is 5 - (H//2)) &
- note the flow_rate of Inlet is NewFlowRate)].
-
-
- /* draw image -- just a TTY version... here is the
- place to interface you own local graphics routines. This one
- just draws a few asterisks on the display
- */
-
- draw_image(Text,Number) :-
- nl,
- write('------------ '),write(Text),write(' ---------------'),nl,
- tty_image(Number),nl.
-
- /* the terminationg conditions are for compatibility with other Prologs */
- tty_image(Number):- 0 >= Number.
- tty_image(N) :-
- write('*'),
- N1 is N - 1,
- tty_image(N1).